/**
 * 
 */
package org.dragonfire.dasm;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;

/**
 * @author Darth Android
 * @date Aug 31, 2006
 */
public class ImgView extends JFrame implements ActionListener {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ImgView img = new ImgView(96, 64);
		img.setVisible(true);
	}

	private BufferedImage img = null;
	private BorderLayout lm = new BorderLayout();
	private JMenuBar mb = new JMenuBar();
	private JMenu file = new JMenu("File");
	private JMenuItem open = new JMenuItem("Open");
	private JMenu save = new JMenu("Save");
	private JMenuItem save8xi = new JMenuItem("8XI");
	private ArrayList<JMenuItem> saveFormats = new ArrayList<JMenuItem>();
	private JMenuItem quit = new JMenuItem("Quit");

	public ImgView(BufferedImage newImage) {
		img = newImage;
		init();
	}

	private void init() {
		setSize(384, 256);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLayout(lm);
		setJMenuBar(mb);
		add(new ImgPanel(), BorderLayout.CENTER);
		mb.add(file);
		file.add(open);
		file.add(save);
		file.add(quit);
		save.add(save8xi);
		for (int i = 0; i < ImageIO.getWriterFormatNames().length; i++) {
			String format = ImageIO.getWriterFormatNames()[i];
			if (format.equals(format.toLowerCase())) {
				JMenuItem m = new JMenuItem(format.toUpperCase());
				saveFormats.add(m);
				save.add(m);
				m.addActionListener(this);
			}
		}
		quit.addActionListener(this);
		open.addActionListener(this);
		save8xi.addActionListener(this);
		setTitle("DASM Image Viwer");
	}

	public ImgView(int sizeX, int sizeY) {
		img = new BufferedImage(sizeX, sizeY, BufferedImage.TYPE_BYTE_BINARY);
		init();
	}

	public class ImgPanel extends JPanel {

		public void paint(Graphics g) {
			g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent e) {
		Object src = e.getSource();
		if (src == quit)
			System.exit(0);
		if (src == open) {
			JFileChooser jf = new JFileChooser();
			jf.showOpenDialog(this);
			try {
				BufferedImage bf = ImageIO.read(jf.getSelectedFile());
				// setSize(img.getWidth(),img.getHeight());
				img.getGraphics().drawImage(bf, 0, 0, img.getWidth(), img.getHeight(), this);
				repaint();
			} catch (Exception ex) {
				// TODO error loading image
			}
		}
		if (saveFormats.contains(src)) {
			JFileChooser jf = new JFileChooser();
			jf.showSaveDialog(this);
			try {
				ImageIO.write(img, ((JMenuItem) src).getText().toLowerCase(), jf.getSelectedFile());
			} catch (Exception ex) {
				// TODO error saving image
			}
		}
	}

	public static byte[] imageData(BufferedImage img) {
		byte[] data = new byte[(int) Math.ceil(img.getHeight() * img.getWidth() / 8.0)];
		int width = img.getWidth();
		int height = img.getHeight();
		for (int x = 0; x < width; x++)
			for (int y = 0; y < height; y++) {
				int bit = y * width + x;
				data[bit / 8] = (byte) (data[bit / 8] | (img.getRGB(x, y) == 0 ? 0 : 1) << bit % 8);
				img.setRGB(x, y, (data[bit / 8] & (1 << bit % 8)) == 0 ? 0 : 0xFFFFFF);
			}
		return data;
	}

	public static BufferedImage imageOf(byte[] data) {
		int x = data[0];
		int y = data[1];
		byte[] newData = new byte[data.length - 2];
		System.arraycopy(data, 2, newData, 0, newData.length);
		return imageOf(newData, x, y);
	}

	public static BufferedImage imageOf(byte[] data, int width, int height) {
		BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
		for (int x = 0; x < width; x++)
			for (int y = 0; y < height; y++) {
				int bit = y * width + x;
				img.setRGB(x, y, (data[bit / 8] & (1 << bit % 8)) == 0 ? 0 : 0xFFFFFF);
			}
		return img;
	}
}
